package com.seafood.controller;

import com.seafood.common.PageResult;
import com.seafood.common.Result;
import com.seafood.dto.TraceabilityDTO;
import com.seafood.dto.TraceabilityQueryDTO;
import com.seafood.service.TraceabilityService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * 溯源控制器
 */
@Tag(name = "溯源管理", description = "产品溯源相关API")
@RestController
@RequestMapping("/trace")
@RequiredArgsConstructor
@Validated
public class TraceabilityController {
    
    private final TraceabilityService traceabilityService;
    
    /**
     * 根据批次号查询溯源信息
     */
    @Operation(summary = "批次号查询溯源", description = "根据批次号查询产品溯源信息")
    @GetMapping("/batch/{batchNumber}")
    public Result<TraceabilityDTO> getTraceabilityByBatch(@PathVariable String batchNumber) {
        try {
            TraceabilityDTO traceability = traceabilityService.getTraceabilityByBatchNumber(batchNumber);
            return Result.success(traceability);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 根据二维码查询溯源信息
     */
    @Operation(summary = "二维码查询溯源", description = "根据二维码内容查询产品溯源信息")
    @GetMapping("/qr")
    public Result<TraceabilityDTO> getTraceabilityByQrCode(@RequestParam String qrCode) {
        try {
            TraceabilityDTO traceability = traceabilityService.getTraceabilityByQrCode(qrCode);
            return Result.success(traceability);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 根据产品ID查询所有溯源信息
     */
    @Operation(summary = "产品溯源列表", description = "根据产品ID查询所有溯源信息")
    @GetMapping("/product/{productId}")
    public Result<List<TraceabilityDTO>> getTraceabilityByProduct(@PathVariable Long productId) {
        try {
            List<TraceabilityDTO> traceabilityList = traceabilityService.getTraceabilityByProductId(productId);
            return Result.success(traceabilityList);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 生成二维码图片
     */
    @Operation(summary = "生成二维码", description = "根据批次号生成二维码图片")
    @GetMapping("/qrcode/{batchNumber}")
    public ResponseEntity<byte[]> generateQRCode(@PathVariable String batchNumber) {
        try {
            byte[] qrCodeImage = traceabilityService.generateQRCode(batchNumber);
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentLength(qrCodeImage.length);
            headers.set("Content-Disposition", "inline; filename=\"" + batchNumber + ".png\"");
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(qrCodeImage);
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }
    
    /**
     * 获取二维码URL
     */
    @Operation(summary = "获取二维码URL", description = "获取二维码访问URL")
    @GetMapping("/qrcode-url/{batchNumber}")
    public Result<String> getQRCodeUrl(@PathVariable String batchNumber) {
        try {
            String qrCodeUrl = traceabilityService.getQRCodeUrl(batchNumber);
            return Result.success(qrCodeUrl);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 创建溯源信息
     */
    @Operation(summary = "创建溯源信息", description = "为产品创建溯源信息")
    @PostMapping
    @PreAuthorize("hasRole('ADMIN')")
    public Result<TraceabilityDTO> createTraceability(@Valid @RequestBody TraceabilityDTO traceabilityDTO) {
        try {
            TraceabilityDTO createdTraceability = traceabilityService.createTraceability(traceabilityDTO);
            return Result.success("溯源信息创建成功", createdTraceability);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 更新溯源信息
     */
    @Operation(summary = "更新溯源信息", description = "更新产品溯源信息")
    @PutMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<TraceabilityDTO> updateTraceability(@PathVariable Long id, 
                                                     @Valid @RequestBody TraceabilityDTO traceabilityDTO) {
        try {
            TraceabilityDTO updatedTraceability = traceabilityService.updateTraceability(id, traceabilityDTO);
            return Result.success("溯源信息更新成功", updatedTraceability);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 删除溯源信息
     */
    @Operation(summary = "删除溯源信息", description = "删除指定溯源信息")
    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<Void> deleteTraceability(@PathVariable Long id) {
        try {
            traceabilityService.deleteTraceability(id);
            return Result.success("溯源信息删除成功", null);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 生成批次号
     */
    @Operation(summary = "生成批次号", description = "为指定产品生成新的批次号")
    @PostMapping("/generate-batch/{productId}")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<String> generateBatchNumber(@PathVariable Long productId) {
        try {
            String batchNumber = traceabilityService.generateBatchNumber(productId);
            return Result.success("批次号生成成功", batchNumber);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 检查批次号是否存在
     */
    @Operation(summary = "检查批次号", description = "检查批次号是否已存在")
    @GetMapping("/check-batch")
    public Result<Boolean> checkBatchNumber(@RequestParam String batchNumber) {
        boolean exists = traceabilityService.existsByBatchNumber(batchNumber);
        return Result.success(!exists); // 返回true表示可用，false表示已存在
    }
    
    /**
     * 分页查询溯源信息
     */
    @Operation(summary = "分页查询溯源信息", description = "分页查询溯源信息")
    @PostMapping("/query")
    @PreAuthorize("hasRole('ADMIN')")
    public Result<PageResult<TraceabilityDTO>> queryTraceability(@RequestBody TraceabilityQueryDTO queryDTO) {
        try {
            PageResult<TraceabilityDTO> pageResult = traceabilityService.queryTraceability(queryDTO);
            return Result.success(pageResult);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
}